package com.own.component.util.excel.util.write.method;

import com.own.component.util.excel.model.Coordinate;
import com.own.component.util.excel.util.write.function.WriteFormatFunction;
import com.own.component.util.excel.util.write.method.base.BaseMetaData;
import com.own.component.util.excel.util.write.model.Style;
import com.own.component.util.excel.util.write.record.CellRecord;
import com.own.component.util.excel.util.write.record.ExcelRecord;

/**
 * BaseValueMethod
 *
 * @author chenxueli
 * @date 2022-06-15 03:14:15
 */
public interface BaseValueMethod extends BaseMetaData {

    /**
     * 设置坐标信息
     *
     * @param x x坐标
     * @param y y坐标
     * @return excel信息
     */
    default ExcelRecord addCoordinate(int x, int y) {
        sheet().addCoordinate(x, y);
        return excel();
    }

    /**
     * 设置坐标信息
     *
     * @param x x坐标
     * @param y y坐标
     * @return excel信息
     */
    default ExcelRecord setCoordinate(int x, int y) {
        sheet().setCoordinate(x, y);
        return excel();
    }

    /**
     * 设置内容
     *
     * @param x     x坐标
     * @param y     y坐标
     * @param value 内容
     * @param style 样式
     * @return 表格对象
     */
    default ExcelRecord setValue(int x, int y, String value, Style style) {
        return setValue(x, y, value, style, true);
    }

    /**
     * 设置内容
     *
     * @param x       x坐标
     * @param y       y坐标
     * @param value   内容
     * @param style   样式
     * @param refresh 是否刷新位置
     * @return 表格对象
     */
    default ExcelRecord setValue(int x, int y, String value, Style style, boolean refresh) {
        var sheet = sheet();
        var key = Coordinate.buildKey(x, y);
        var writeMap = sheet.getWriteMap();
        var list = sheet.getList();
        if (writeMap.containsKey(key)) {
            var item = list.get(writeMap.get(key));
            item.setValue(value);
            item.setStyle(style);
        } else {
            var item = new CellRecord(x, y, value, style);
            list.add(item);
            writeMap.put(key, list.size() - 1);
        }
        if (refresh) {
            sheet.setCoordinate(x, y);
        }
        return excel();
    }

    /**
     * 获取x坐标
     *
     * @return x坐标
     */
    default int getX() {
        return sheet().getCurrent().getX();
    }

    /**
     * 获取y坐标
     *
     * @return y坐标
     */
    default int getY() {
        return sheet().getCurrent().getY();
    }

    /**
     * 设置内容
     *
     * @param value 内容
     * @return 表格对象
     */
    default ExcelRecord setValue(Object value) {
        return setValue(value.toString());
    }

    /**
     * 设置内容
     *
     * @param value 内容
     * @return 表格对象
     */
    default ExcelRecord setValue(String value) {
        return setValue(getX(), getY(), value, sheet().getDefaultStyle());
    }

    /**
     * 设置内容
     *
     * @param value 内容
     * @param style 样式
     * @return 表格对象
     */
    default ExcelRecord setValue(Object value, Style style) {
        return setValue(value.toString(), style);
    }

    /**
     * 设置内容
     *
     * @param value 内容
     * @param style 样式
     * @return 表格对象
     */
    default ExcelRecord setValue(String value, Style style) {
        return setValue(getX(), getY(), value, style);
    }

    /**
     * 设置内容
     *
     * @param x     x坐标
     * @param y     y坐标
     * @param value 内容
     * @return 表格对象
     */
    default ExcelRecord setValue(int x, int y, Object value) {
        return setValue(getX(), getY(), value.toString());
    }

    /**
     * 设置内容
     *
     * @param x     x坐标
     * @param y     y坐标
     * @param value 内容
     * @return 表格对象
     */
    default ExcelRecord setValue(int x, int y, String value) {
        return setValue(getX(), getY(), value, sheet().getDefaultStyle());
    }

    /**
     * 设置内容
     *
     * @param x     x坐标
     * @param y     y坐标
     * @param value 内容
     * @param style 样式
     * @return 表格对象
     */
    default ExcelRecord setValue(int x, int y, Object value, Style style) {
        return setValue(x, y, value.toString(), style);
    }

    /**
     * 设置单元格批注
     *
     * @param comment 批注信息
     * @return 表格对象
     */
    default ExcelRecord setComment(String comment) {
        var sheet = sheet();
        return this.setComment(sheet.getX(), sheet.getY(), comment);
    }

    /**
     * 设置单元格批注
     *
     * @param x       x坐标
     * @param y       y坐标
     * @param comment 样式
     * @return 表格对象
     */
    default ExcelRecord setComment(int x, int y, String comment) {
        var sheet = sheet();
        var key = Coordinate.buildKey(x, y);
        var writeMap = sheet.getWriteMap();
        var list = sheet.getList();
        if (!writeMap.containsKey(key)) {
            setValue(x, y, "", null);
        }
        var item = list.get(writeMap.get(key));
        item.setComment(comment);
        // 设置新的坐标
        sheet.setCoordinate(x, y);
        return excel();
    }

    /**
     * 设置数据格式信息
     *
     * @param writeFormatFunction 数据格式信息
     * @return 表格对象
     */
    default ExcelRecord setDataFormat(WriteFormatFunction writeFormatFunction) {
        var sheet = sheet();
        var key = sheet.getCurrent().key();
        var writeMap = sheet.getWriteMap();
        if (writeMap.containsKey(key)) {
            var list = sheet.getList();
            var item = list.get(writeMap.get(key));
            item.setDataFormat(writeFormatFunction);
        } else {
            var current = sheet.getCurrent();
            setValue(current.getX(), current.getY(), "", null);
            setDataFormat(current.getX(), current.getY(), writeFormatFunction);
        }
        return excel();
    }

    /**
     * 设置数据格式信息
     *
     * @param x                   x
     * @param y                   y
     * @param writeFormatFunction 数据格式信息
     * @return 表格对象
     */
    default ExcelRecord setDataFormat(int x, int y, WriteFormatFunction writeFormatFunction) {
        var sheet = sheet();
        var key = Coordinate.buildKey(x, y);
        var writeMap = sheet.getWriteMap();
        if (writeMap.containsKey(key)) {
            var list = sheet.getList();
            var item = list.get(writeMap.get(key));
            item.setDataFormat(writeFormatFunction);
        } else {
            setValue(x, y, "", null);
            setDataFormat(x, y, writeFormatFunction);
        }
        return excel();
    }

}
